package com.rzico.sbl.ui.report.dispatch

import android.text.Editable
import android.text.TextWatcher
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.lifecycleScope
import com.google.gson.Gson
import com.jeremyliao.liveeventbus.LiveEventBus
import com.rzico.sbl.R
import com.rzico.sbl.databinding.ActivityReportDispatchFirstBinding
import com.rzico.sbl.model.DispatchBucket
import com.rzico.sbl.other.serviceId
import com.rzico.sbl.other.serviceStep
import com.rzico.sbl.ui.report.other.ReportService
import com.rzico.sbl.viewmodel.ReportDispatchViewModel
import com.xinnuo.common.decoration.SpaceTBDecoration
import com.xinnuo.common.extend.conditionElse
import com.xinnuo.common.extend.find
import com.xinnuo.common.extend.formatDecimal
import com.xinnuo.common.extend.get
import com.xinnuo.common.extend.getExtra
import com.xinnuo.common.extend.goneValue
import com.xinnuo.common.extend.oneClick
import com.xinnuo.common.extend.orEmpty
import com.xinnuo.common.extend.startActivityEx
import com.xinnuo.common.extend.visibleValue
import com.xinnuo.common.helper.doubleValue
import com.xinnuo.common.helper.intValue
import com.xinnuo.common.listener._TextWatcher
import com.xinnuo.common_ui.base.BaseActivity
import com.xinnuo.common_ui.base.addItems
import com.xinnuo.common_ui.utils.bindLifeCycle
import com.xinnuo.common_ui.utils.showListDialog
import com.xinnuo.common_ui.utils.subscribeByFinally
import com.xinnuo.common_ui.utils.subscribeBySuccess
import com.xinnuo.slimadapter.SlimAdapter
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlin.math.abs

class ReportDispatchFirstActivity : BaseActivity(R.layout.activity_report_dispatch_first) {

    private val mBinding by lazy { ActivityReportDispatchFirstBinding.bind(getRootView()) }

    private val mBarrelList = ArrayList<DispatchBucket>()
    private val mTotalEvent = MutableLiveData(mList.size)
    private lateinit var mTotalView: View
    private lateinit var mShipId: String
    private lateinit var mOrderSn: String
    private lateinit var mShippingSn: String
    private var mBarrelPirce = "0.00" //空桶总金额

    override fun getViewModel() = get<ReportDispatchViewModel>()

    override fun initData() {
        initTitle(title = "空桶")

        initLayout()
        observeTotal()

        getData()
    }

    private fun initLayout() {
        mBinding.listLayout.apply {
            swipeRefresh.isEnabled = false

            recycleList.also { layout ->
                layout.addItemDecoration(SpaceTBDecoration())

                mAdapter = SlimAdapter.creator()
                    .register<DispatchBucket>(R.layout.item_report_dispatch_bucket) { jector, bean, index ->
                        jector.apply {
                            text(R.id.item_bucket_barrel, bean.name)

                            // 送出桶
                            with<EditText>(R.id.item_bucket_out) {
                                if (it.tag != null && it.tag is TextWatcher) {
                                    it.removeTextChangedListener(it.tag as TextWatcher)
                                }

                                it.setText(bean.quantity.orEmpty("0"))
                                it.setSelection(it.text.length)

                                val textWatcher = object : _TextWatcher() {
                                    override fun afterTextChanged(s: Editable) {
                                        bean.quantity = s.toString()

                                        calculateItem(bean) {
                                            getView<TextView>(R.id.item_bucket_qian)
                                                .text = bean.arrearsQuantity
                                            getView<TextView>(R.id.item_bucket_huan)
                                                .text = bean.repayQuantity
                                            getView<TextView>(R.id.item_bucket_new)
                                                .text = (bean.borrow.intValue
                                                    - bean.adAdvanceStock.intValue
                                                    + bean.backQuantity.intValue
                                                    + bean.arrearsQuantity.intValue
                                                    - bean.repayQuantity.intValue).toString()
                                        }
                                    }
                                }
                                it.addTextChangedListener(textWatcher)
                                it.tag = textWatcher
                            }

                            // 以往欠桶
                            with<EditText>(R.id.item_bucket_old) {
                                if (it.tag != null && it.tag is TextWatcher) {
                                    it.removeTextChangedListener(it.tag as TextWatcher)
                                }

                                it.setText(bean.borrow.orEmpty("0"))
                                it.setSelection(it.text.length)
                                it.isEnabled = serviceId in ReportService.MODE_DRIVER

                                val textWatcher = object : _TextWatcher() {
                                    override fun afterTextChanged(s: Editable) {
                                        bean.borrow = s.toString()

                                        calculateItem(bean) {
                                            getView<TextView>(R.id.item_bucket_qian)
                                                .text = bean.arrearsQuantity
                                            getView<TextView>(R.id.item_bucket_huan)
                                                .text = bean.repayQuantity
                                            getView<TextView>(R.id.item_bucket_new)
                                                .text = (bean.borrow.intValue
                                                    - bean.adAdvanceStock.intValue
                                                    + bean.backQuantity.intValue
                                                    + bean.arrearsQuantity.intValue
                                                    - bean.repayQuantity.intValue).toString()
                                        }
                                    }
                                }
                                it.addTextChangedListener(textWatcher)
                                it.tag = textWatcher
                            }

                            // 入库
                            with<EditText>(R.id.item_bucket_in) {
                                if (it.tag != null && it.tag is TextWatcher) {
                                    it.removeTextChangedListener(it.tag as TextWatcher)
                                }

                                it.setText(bean.returnQuantity.orEmpty("0"))
                                it.setSelection(it.text.length)

                                val textWatcher = object : _TextWatcher() {
                                    override fun afterTextChanged(s: Editable) {
                                        bean.returnQuantity = s.toString()

                                        calculateItem(bean) {
                                            getView<TextView>(R.id.item_bucket_qian)
                                                .text = bean.arrearsQuantity
                                            getView<TextView>(R.id.item_bucket_huan)
                                                .text = bean.repayQuantity
                                            getView<TextView>(R.id.item_bucket_new)
                                                .text = (bean.borrow.intValue
                                                    - bean.adAdvanceStock.intValue
                                                    + bean.backQuantity.intValue
                                                    + bean.arrearsQuantity.intValue
                                                    - bean.repayQuantity.intValue).toString()
                                        }
                                    }
                                }
                                it.addTextChangedListener(textWatcher)
                                it.tag = textWatcher
                            }

                            // 司机还桶
                            with<EditText>(R.id.item_bucket_driver) {
                                if (it.tag != null && it.tag is TextWatcher) {
                                    it.removeTextChangedListener(it.tag as TextWatcher)
                                }

                                it.setText(bean.backQuantity.orEmpty("0"))
                                it.setSelection(it.text.length)

                                val textWatcher = object : _TextWatcher() {
                                    override fun afterTextChanged(s: Editable) {
                                        bean.backQuantity = s.toString()

                                        calculateItem(bean) {
                                            getView<TextView>(R.id.item_bucket_qian)
                                                .text = bean.arrearsQuantity
                                            getView<TextView>(R.id.item_bucket_huan)
                                                .text = bean.repayQuantity
                                            getView<TextView>(R.id.item_bucket_new)
                                                .text = (bean.borrow.intValue
                                                    - bean.adAdvanceStock.intValue
                                                    + bean.backQuantity.intValue
                                                    + bean.arrearsQuantity.intValue
                                                    - bean.repayQuantity.intValue).toString()
                                        }
                                    }
                                }
                                it.addTextChangedListener(textWatcher)
                                it.tag = textWatcher
                            }

                            text(R.id.item_bucket_qian, bean.arrearsQuantity.orEmpty("0")) //欠桶
                            text(R.id.item_bucket_huan, bean.repayQuantity.orEmpty("0"))   //还桶

                            // 押桶
                            text(R.id.item_bucket_ya, bean.pledgeQuantity)
                            text(R.id.item_bucket_money2, bean.pledge.formatDecimal())
                            // 买桶
                            text(R.id.item_bucket_mai, bean.buyQuantity)
                            text(R.id.item_bucket_money3, bean.buy.formatDecimal())
                            // 退桶
                            text(R.id.item_bucket_tui, bean.refundsQuantity)
                            text(R.id.item_bucket_money4, bean.refunds.formatDecimal())

                            // 兑换桶
                            text(R.id.item_bucket_change, bean.transQuantity.orEmpty("0"))
                            // 累计欠桶
                            text(
                                R.id.item_bucket_new,
                                (bean.borrow.intValue
                                        - bean.adAdvanceStock.intValue
                                        + bean.backQuantity.intValue
                                        + bean.arrearsQuantity.intValue
                                        - bean.repayQuantity.intValue).toString()
                            )

                            // 预存桶抵扣
                            text(R.id.item_bucket_store, bean.adAdvanceStock)

                            text(R.id.item_bucket_one, bean.percent1)   //外品牌1:1
                            text(R.id.item_bucket_two, bean.percent2)   //外品牌2:1
                            text(R.id.item_bucket_three, bean.percent3) //外品牌3:1
                            text(R.id.item_bucket_fill, bean.percent4)  //外品牌补差价
                            text(R.id.item_bucket_money1, bean.differPrice.formatDecimal()) //补差价金额

                            text(R.id.item_bucket_memo, bean.memo1) //备注

                            visibility(
                                R.id.item_bucket_del,
                                goneValue { bean.quantity.intValue > 0 }
                            )

                            visibility(
                                R.id.item_bucket_ya_ll,
                                visibleValue { bean.pledgeQuantity.intValue > 0 }
                            )

                            visibility(
                                R.id.item_bucket_mai_ll,
                                visibleValue { bean.buyQuantity.intValue > 0 }
                            )

                            visibility(
                                R.id.item_bucket_tui_ll,
                                visibleValue { bean.refundsQuantity.intValue > 0 }
                            )

                            visibility(
                                R.id.item_bucket_store_ll,
                                visibleValue { bean.adAdvanceStock.intValue > 0 }
                            )

                            visibility(
                                R.id.item_bucket_other_ll,
                                visibleValue {
                                    bean.percent1.intValue > 0
                                            || bean.percent2.intValue > 0
                                            || bean.percent3.intValue > 0
                                            || bean.percent4.intValue > 0
                                }
                            )

                            visibility(
                                R.id.item_bucket_memo_ll,
                                goneValue { bean.memo1.isNullOrEmpty() }
                            )

                            clicked(R.id.item_bucket_del) {
                                mList.removeAt(index)
                                mTotalEvent.value = mList.size

                                mAdapter.apply {
                                    notifyItemRemoved(index)
                                    notifyItemRangeChanged(index, mList.size - index)
                                }
                            }

                            clicked(R.id.item_bucket_edit) {
                                startActivityEx<ReportDispatchBucketActivity>(
                                    "data" to bean,
                                    "index" to index
                                )
                            }
                        }
                    }
                    .attachTo(layout)
                    .addFooter(baseContext, R.layout.footer_report_bucket) { _, view ->
                        view.also { mTotalView = it }
                            .find<Button>(R.id.bucket_add)
                            .oneClick {
                                if (mBarrelList.isEmpty()) {
                                    showToast("获取品牌信息失败！")
                                    return@oneClick
                                }

                                showLoopDialog()
                            }
                    }
            }
        }
    }

    override fun initListener() {
        mShipId = intent.getExtra("shipId")
        mOrderSn = intent.getExtra("orderSn")
        mShippingSn = intent.getExtra("shippingSn")

        mBinding.apply {
            btNext.oneClick {
                if (mBarrelList.isEmpty()) {
                    showToast("获取空桶信息失败，请返回重试")
                    return@oneClick
                }

                saveBucketData()
            }
        }

        // 观察空桶编辑
        LiveEventBus
            .get("dispatchFirst", DispatchBucket::class.java)
            .observe(this) {
                if (it.position > -1) mList[it.position] = it
                else mList.add(it)

                mTotalEvent.value = mList.size
                mAdapter.notifyDataSetChanged()
            }
    }

    /**
     * 空桶品牌列表
     */
    override fun getData(index: Int, isLoading: Boolean) {
        getViewModel()
            .getBarrelList(mShipId)
            .bindLifeCycle(getLifecycleOwner())
            .subscribeByFinally(
                event = getViewModel(),
                onSuccess = { value ->
                    mBarrelList.clear()
                    mList.clear()

                    mBarrelList.addItems(value)
                    mList.addItems(value.filter { it.show })
                    mTotalEvent.value = mList.size

                    mAdapter.setDataList(mList)
                }
            )
    }

    /**
     * 保存空桶信息
     */
    private fun saveBucketData() {
        mList.forEach {
            it as DispatchBucket
            it.quantity = it.quantity.orEmpty("0")
            it.borrow = it.borrow.orEmpty("0")
            it.returnQuantity = it.returnQuantity.orEmpty("0")
            it.backQuantity = it.backQuantity.orEmpty("0")
        }

        getViewModel()
            .dispatchFirst(
                "sn" to mShippingSn,
                "barrelPrice" to mBarrelPirce,
                "body" to Gson().toJson(mList)
            )
            .bindLifeCycle(getLifecycleOwner())
            .subscribeBySuccess(
                event = getViewModel(),
                onSuccess = {
                    when (serviceStep) {
                        "3" ->
                            startActivityEx<ReportDispatchSecondActivity>(
                                "shipId" to mShipId,
                                "orderSn" to mOrderSn,
                                "shippingSn" to mShippingSn
                            )
                        else -> {
                            startActivityEx<ReportDispatchRottenActivity>(
                                "shipId" to mShipId,
                                "orderSn" to mOrderSn,
                                "shippingSn" to mShippingSn
                            )
                        }
                    }
                }
            )
    }

    /**
     * 添加回桶弹框
     */
    private fun showLoopDialog() {
        val items = mBarrelList.filter {
            mList.none { item ->
                (item as DispatchBucket).id == it.id
            }
        }

        items.isNotEmpty()
            .conditionElse(
                actionTrue = {
                    showListDialog(
                        title = "请选择品牌",
                        items = items.map { it.name.orEmpty() },
                        listener = { index, _ ->
                            startActivityEx<ReportDispatchBucketActivity>(
                                "data" to items[index]
                            )
                        }
                    )
                },
                actionFalse = { showToast("暂无其他系列品牌") }
            )
    }

    /**
     * 欠桶/还桶计算
     */
    private fun calculateItem(bean: DispatchBucket, onNext: () -> Unit) =
        lifecycleScope.launch(Dispatchers.IO) {
            val countDriver = bean.backQuantity.intValue
            val countOut = bean.quantity.intValue
            val countIn = bean.returnQuantity.intValue
            val countYa = bean.pledgeQuantity.intValue
            val countMai = bean.buyQuantity.intValue
            val countTui = bean.refundsQuantity.intValue
            val countChange = bean.transQuantity.intValue

            val totalCount =
                countOut - countIn - countDriver - countYa - countMai + countTui - countChange

            when {
                totalCount > 0 -> {
                    bean.arrearsQuantity = totalCount.toString()
                    bean.repayQuantity = "0"
                }
                totalCount < 0 -> {
                    bean.arrearsQuantity = "0"
                    bean.repayQuantity = abs(totalCount).toString()
                }
                else -> {
                    bean.arrearsQuantity = "0"
                    bean.repayQuantity = "0"
                }
            }

            withContext(Dispatchers.Main) {
                mTotalEvent.value = mList.size

                onNext.invoke()
            }
        }

    /**
     * 观察合计信息
     */
    private fun observeTotal() {
        mTotalEvent
            .observe(this) { value ->
                mTotalView
                    .apply {
                        find<LinearLayout>(R.id.bucket_total_ll).isVisible = value > 0

                        if (value > 0) {
                            var countOutput = 0
                            var countInput = 0
                            var countQian = 0
                            var countHuan = 0

                            var countFill = 0
                            var countYa = 0
                            var countMai = 0
                            var countTui = 0
                            var amountFill = 0.0
                            var amountYa = 0.0
                            var amountMai = 0.0
                            var amountTui = 0.0

                            mList.forEach {
                                it as DispatchBucket
                                countOutput += it.quantity.intValue
                                countInput += it.returnQuantity.intValue
                                countQian += it.arrearsQuantity.intValue
                                countHuan += it.repayQuantity.intValue

                                countFill += it.percent4.intValue
                                countYa += it.pledgeQuantity.intValue
                                countMai += it.buyQuantity.intValue
                                countTui += it.refundsQuantity.intValue
                                amountFill += it.differPrice.doubleValue
                                amountYa += it.pledge.doubleValue
                                amountMai += it.buy.doubleValue
                                amountTui += it.refunds.doubleValue
                            }

                            find<TextView>(R.id.bucket_ya_count).text = "$countYa"
                            find<TextView>(R.id.bucket_mai_count).text = "$countMai"
                            find<TextView>(R.id.bucket_tui_count).text = "$countTui"
                            find<TextView>(R.id.bucket_fill_count).text = "$countFill"

                            find<TextView>(R.id.bucket_ya_amount).text = amountYa.formatDecimal()
                            find<TextView>(R.id.bucket_mai_amount).text = amountMai.formatDecimal()
                            find<TextView>(R.id.bucket_tui_amount).text = amountTui.formatDecimal()
                            find<TextView>(R.id.bucket_fill_amount).text = amountFill.formatDecimal()

                            find<TextView>(R.id.bucket_out_count).text = "$countOutput"
                            find<TextView>(R.id.bucket_in_count).text = "$countInput"
                            find<TextView>(R.id.bucket_qian_count).text = "$countQian"
                            find<TextView>(R.id.bucket_huan_count).text = "$countHuan"

                            find<TextView>(R.id.bucket_total).text =
                                "($amountYa + $amountMai - $amountTui + $amountFill) = ${
                                    (amountYa + amountMai - amountTui + amountFill)
                                        .formatDecimal()
                                        .also { mBarrelPirce = it }
                                }"
                        }
                    }
            }
    }

}